/*
 * Copyright (C) 2010-2012 Geometer Plus <contact@geometerplus.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 */

package cn.dns.reader.network;

import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.text.TextUtils;
import android.widget.RemoteViews;
import android.widget.Toast;

import com.hctforgreen.greenservice.R;
import com.hctforgreen.greenservice.ctr.DbController;
import com.hctforgreen.greenservice.ctr.HctController;
import com.hctforgreen.greenservice.model.BookListEntity.BookEntity;
import com.hctforgreen.greenservice.model.BookZipTxtEntity;
import com.hctforgreen.greenservice.model.ResultEntity;
import com.hctforgreen.greenservice.service.HctApplication;
import com.hctforgreen.greenservice.utils.DownloadBookLstInitFinishUtil;
import com.hctforgreen.greenservice.utils.EntryCatalogUtil;
import com.hctforgreen.greenservice.utils.HctConstants;
import com.hctforgreen.greenservice.utils.HctResult;
import com.hctforgreen.greenservice.utils.LogUtil;
import com.hctforgreen.greenservice.utils.LoginResultStoreUtil;
import com.mato.sdk.proxy.Address;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;

import cn.dns.zlibrary.core.network.ZLNetworkException;
import cn.dns.zlibrary.core.network.ZLNetworkManager;
import cn.dns.zlibrary.core.network.ZLNetworkRequest;

public class BookDownloaderService extends Service {
    private Context actContext;

    private boolean updateDateServicestate = false;
    private boolean isFromDownloadManager = false;
    public static final String SHOW_NOTIFICATIONS_KEY = "org.geometerplus.android.fbreader.network.ShowNotifications";
    public static final String TITLE_KEY = "org.geometerplus.android.fbreader.network.Title";
    public static final String BOOK_FORMAT_KEY = "org.geometerplus.android.fbreader.network.BookFormat";
    private Address address;

    public interface Notifications {
        int DOWNLOADING_STARTED = 0x0001;
        int ALREADY_DOWNLOADING = 0x0002;
        int ALL = 0x0003;
    }

    private Set<BookEntity> mDownloadingUrls = Collections.synchronizedSet(new HashSet<BookEntity>());

    /**
     * 等待下载队列
     */
    private List<BookEntity> mWaitingUrls = Collections
            .synchronizedList(new ArrayList<BookEntity>());
    private Set<Integer> myOngoingNotifications = new HashSet<Integer>();
    private volatile int myServiceCounter;

    private void doStart() {
        ++myServiceCounter;
    }

    private void doStop() {
        if (--myServiceCounter == 0) {
            stopSelf();
        }
        try {
            unregisterReceiver(receive);
        } catch (Exception e) {
            LogUtil.i("服务注册", "Receiver not registered" + e);
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return new BookDownloaderInterface.Stub() {
            public boolean isBeingDownloaded(String url) {
                //判断要下载的资料URL是否在正在下载或者等待下载的队列中
                if (contains(url)) {
                    return true;
                } else {
                    return false;
                }
            }

            @Override
            public boolean hasDownloadingUrl() throws RemoteException {
                if (mDownloadingUrls.size() > 0) {
                    return true;
                }
                return false;
            }

            @Override
            public boolean cancelDownloadingUrl(String url)
                    throws RemoteException {
                for (BookEntity entity : mDownloadingUrls) {
                    if (entity.download_url.equals(url)) {
                        entity.bookZipState = HctConstants.ON_ACTIVITY_KEY_BOOK_ZIP_STATE_ALREADY_CANCEL;
                        return true;
                    }
                }
                Iterator<BookEntity> keys = mWaitingUrls.iterator();
                BookEntity key = null;
                while (keys.hasNext()) {
                    key = (BookEntity) keys.next();
                    if (key.download_url.equals(url)) {
                        keys.remove();
                        return true;
                    }
                }
                return false;
            }
        };
    }

    @Override
    public void onDestroy() {
        final NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        for (int notificationId : myOngoingNotifications) {
            notificationManager.cancel(notificationId);
            clearDownloadingURLs(notificationManager, notificationId);
        }
        myOngoingNotifications.clear();
        try {
            unregisterReceiver(receive);
        } catch (Exception e) {
            LogUtil.i("服务注册", "Receiver not registered" + e);
        }

        super.onDestroy();
    }

    /**
     * 在下载Service销毁时，如果还有没有下载完成的，设置为下载失败状态
     *
     * @param notificationId
     */
    private void clearDownloadingURLs(NotificationManager notificationManager,
                                      int notificationId) {

        for (BookEntity bookEntity : mDownloadingUrls) {
            if (bookEntity == null) {
                return;
            }
            if (bookEntity.notificationId == notificationId) {
                if (bookEntity.doWhatClick
                        .equals(HctConstants.ON_ACTIVITY_KEY_DO_UPDATE_CLICK)) {
                    /**
                     *2016 12 16 390778
                     * 增加判断
                     * true  进行数据库操作
                     * false  进行保存到list中，等待操作完成后进行插入数据库
                     */
                    if (updateDateServicestate) {
                        updateBookProgress(bookEntity, 100);
                        updateBookZipState(
                                bookEntity,
                                HctConstants.ON_ACTIVITY_KEY_BOOK_ZIP_STATE_ANALISIS_DONE);
                    } else {
                        bookEntity.progress = 100;
                        bookEntity.bookZipState = HctConstants.ON_ACTIVITY_KEY_BOOK_ZIP_STATE_ANALISIS_DONE;
                        bookStateList.add(bookEntity);
                    }

                    sendDownloadedProgressBroadcast(bookEntity.download_url,
                            true, 100, bookEntity);
                } else {
                    /**
                     *2016 12 16 390778
                     * 增加判断
                     * true  进行数据库操作
                     * false  进行保存到list中，等待操作完成后进行插入数据库
                     */
                    if (updateDateServicestate) {
                        updateBookProgress(bookEntity, 0);
                        updateBookZipState(
                                bookEntity,
                                HctConstants.ON_ACTIVITY_KEY_BOOK_ZIP_STATE_DOWNLOAD_FAIL);
                    } else {
                        bookEntity.progress = 0;
                        bookEntity.bookZipState = HctConstants.ON_ACTIVITY_KEY_BOOK_ZIP_STATE_DOWNLOAD_FAIL;
                        bookStateList.add(bookEntity);
                    }

                    sendDownloadedProgressBroadcast(bookEntity.download_url,
                            true, 0, bookEntity);
                }
                remove(bookEntity.download_url);
                String title = bookEntity.displayName;
                notificationManager.notify(notificationId, createDownloadFinishNotification(title, 0, bookEntity, notificationId));
            }
        }
    }

    List<BookEntity> bookStateList = new ArrayList<BookEntity>();

    /**
     * 2016 12 16 390778
     * 增加
     * 等待线程，在接收到数据库完成广播的同时，开始操作数据库进行插入状态
     */
    class MyThread extends Thread {
        @Override
        public void run() {
            LogUtil.i("test", "启动线程");
            LogUtil.i("liststatebook2..", "需要进行操作的书的多少" + bookStateList.size());
            while (true) {
                LogUtil.i("while", "进入while");

                if (bookStateList.get(bookStateList.size() - 1).progress == 99 || bookStateList.get(bookStateList.size() - 1).progress == 100) {
                    break;
                }

                if (DownloadBookLstInitFinishUtil.getDownloadBookFinished(getApplication()))
                    break;

                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            LogUtil.i("while结束", "while结束");
            for (BookEntity book : bookStateList) {
                updateBookProgress(book);
                updateBookZipState(book);
            }

        }
    }

    private MyReceive receive;

    /**
     * 2016 12 16
     * 增加
     * 广播接收
     */
    class MyReceive extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            LogUtil.i("startReceive", "开始接收广播");
            LogUtil.i("当前状态state", updateDateServicestate + "");
            LogUtil.i("liststatebook2", "需要进行操作的书的多少" + bookStateList.size());
            new MyThread().start();
        }
    }

    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
        //判断是否是在下载管理下载书
        isFromDownloadManager = intent.getBooleanExtra("isFromDownloadManager", false);
        if (isFromDownloadManager) {
            /**
             * 2016 12 16 390778
             * 增加状态，增加服务接收器
             * 用于接收数据库完成的广播
             */
            updateDateServicestate = intent.getBooleanExtra("updateDateServicestate", true);
        } else {
            updateDateServicestate = true;
        }
        LogUtil.i("Service updateDateServicestate", "当前状态为：" + updateDateServicestate);
        LogUtil.i("startReceive", "注册了广播.........");
        receive = new MyReceive();
        IntentFilter filter = new IntentFilter();
        filter.addAction("com.hctforgreen.greenservice");
        try {
            getApplication().registerReceiver(receive, filter);
        } catch (Exception e) {
            e.printStackTrace();
        }

        //保存在插入数据库之前数据的状态
        if (bookStateList == null) {
            bookStateList = new ArrayList<BookEntity>();
        }
        doStart();

        if (intent == null) {
            doStop();
            return;
        }
        final Uri uri = intent.getData();
        if (uri == null) {
            doStop();
            return;
        }
        intent.setData(null);

        final int notifications = intent.getIntExtra(SHOW_NOTIFICATIONS_KEY, 0);

        final String url = uri.toString();
        //判断是什么类型的资料 zip pdf word
        final String bookFormat = intent.getStringExtra(BOOK_FORMAT_KEY);
        BookEntity bookEntity = (BookEntity) intent.getSerializableExtra(HctConstants.ON_ACTIVITY_KEY_BOOK_ENTITY);
        String address = intent.getStringExtra("address.host");
        int port = intent.getIntExtra("address.port", 8123);
        if (!TextUtils.isEmpty(address)) {
            try {
                this.address = new Address(address, port);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        String cleanURL = bookEntity.download_url;
        if (cleanURL == null) {
            cleanURL = url;
        }

        if (contains(url)) {
            if ((notifications & Notifications.ALREADY_DOWNLOADING) != 0) {
                Toast.makeText(getApplicationContext(), getString(R.string.already_downloading), Toast.LENGTH_SHORT).show();
            }
            doStop();
            return;
        }

        String fileName = BookEntity.makeBookFileName(cleanURL, bookFormat, getApplicationContext());
        if (fileName == null) {
            doStop();
            return;
        }

        int index = fileName.lastIndexOf(File.separator);
        if (index != -1) {
            final String dir = fileName.substring(0, index);
            final File dirFile = new File(dir);
            //390694
            //隐藏图片、视频等等媒体文件，不能让图库扫描到
            try {
                new File(dirFile, ".nomedia").createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }

            if (!dirFile.exists() && !dirFile.mkdirs()) {
                Toast.makeText(getApplicationContext(), getString(R.string.cannot_create_directory).replace(
                        "%s", dirFile.getPath()), Toast.LENGTH_SHORT).show();
                doStop();
                return;
            }
            if (!dirFile.exists() || !dirFile.isDirectory()) {
                Toast.makeText(getApplicationContext(), getString(R.string.cannot_create_directory).replace(
                        "%s", dirFile.getPath()), Toast.LENGTH_SHORT).show();
                doStop();
                return;
            }
        }

        final File fileFile = new File(fileName);
        if (fileFile.exists()) {
            if (!fileFile.isFile()) {
                Toast.makeText(getApplicationContext(), getString(R.string.cannot_create_file).replace("%s", fileFile.getPath()), Toast.LENGTH_SHORT).show();
                doStop();
                return;
            }

            // doStop();
            /**
             * TODO:点击已经存在文件的下载链接会去调用阅读器的功能
             */
            // startActivity(getStartEntryCatalogIntent(bookEntity));
            // return;
        }
        String title = intent.getStringExtra(TITLE_KEY);
        if (title == null || title.length() == 0) {
            title = fileFile.getName();
        }

        if (mDownloadingUrls.size() < 3) {
            if ((notifications & Notifications.DOWNLOADING_STARTED) != 0) {
                Toast.makeText(getApplicationContext(), getString(R.string.downloading_started), Toast.LENGTH_SHORT).show();
            }
            Util.tryToDeleteBookZip(bookEntity, getApplicationContext());
            startFileDownload(bookEntity, "", fileFile, title);
            addDownloadCount(getApplicationContext(), bookEntity.bookName);
            addDownloadRecord(getApplicationContext(), bookEntity.bookName);
        } else {
            mWaitingUrls.add(bookEntity);
            updateBookZipState(bookEntity, HctConstants.ON_ACTIVITY_KEY_BOOK_ZIP_STATE_DOWNLOAD_WAITING);
            sendDownloadedProgressBroadcast(cleanURL, true, -1, bookEntity);
            doStop();
        }
    }


    private boolean addDownloadFromWaitingUrls() {
        if (mDownloadingUrls.size() < 3 && mWaitingUrls.size() > 0) {

            Iterator<BookEntity> keys = mWaitingUrls.iterator();
            if (keys.hasNext()) {
                BookEntity key = (BookEntity) keys.next();
                keys.remove();
                String fileName = BookEntity.makeBookFileName(key.download_url,
                        key.suffix, getApplicationContext());
                final File file = new File(fileName);

                Util.tryToDeleteBookZip(key, getApplicationContext());

                startFileDownload(key, "", file, key.displayName);
                addDownloadCount(getApplicationContext(), key.bookName);
            }
            return true;
        }
        return false;
    }

    private void addDownloadRecord(final Context context, final String bookName) {
        @SuppressLint("HandlerLeak") final Handler handler = new Handler() {
            public void handleMessage(Message msg) {

                HctResult hctResult = new HctResult();
                switch (msg.what) {
                    case HctConstants.STATUS_SUCCESS:

                        hctResult = (HctResult) msg.obj;

                        ResultEntity entity = (ResultEntity) hctResult.data;

                        break;

                    case HctConstants.STATUS_FAILD:

                        break;
                }
            }

        };
        new Thread() {
            public void run() {
                Message message = new Message();
                try {
                    HctController controller = new HctController(context);

                    HctResult result = controller.addDownloadRecord(bookName,
                            LoginResultStoreUtil.get(context).personId);
                    if (result.status == HctConstants.STATUS_SUCCESS) {
                        message.what = result.status;
                        message.obj = result;
                    } else {
                        message.what = HctConstants.STATUS_FAILD;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                handler.sendMessage(message);
            }
        }.start();
    }

    private void addDownloadCount(final Context context, final String bookName) {

        @SuppressLint("HandlerLeak") final Handler handler = new Handler() {
            public void handleMessage(Message msg) {

                HctResult hctResult = new HctResult();
                switch (msg.what) {
                    case HctConstants.STATUS_SUCCESS:

                        hctResult = (HctResult) msg.obj;

                        ResultEntity entity = (ResultEntity) hctResult.data;

                        break;

                    case HctConstants.STATUS_FAILD:

                        break;
                }
            }

        };
        new Thread() {
            public void run() {
                Message message = new Message();
                try {
                    HctController controller = new HctController(context);

                    HctResult result = controller.addDownloadCount(context,
                            bookName);
                    if (result.status == HctConstants.STATUS_SUCCESS) {
                        message.what = result.status;
                        message.obj = result;
                    } else {
                        message.what = HctConstants.STATUS_FAILD;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                handler.sendMessage(message);
            }
        }.start();
    }

    private Notification createDownloadCancelNotification(File file,
                                                          String title) {
        final String tickerText = getApplicationContext().getString(
                R.string.download_cancel_hint);
        final String contentText = getApplicationContext().getString(
                R.string.download_cancel_hint);
        //未升级6.0的api之前使用的方法 start
//		final Notification notification = new Notification(
//				android.R.drawable.stat_sys_download_done, tickerText,
//				System.currentTimeMillis());
//		notification.flags |= Notification.FLAG_AUTO_CANCEL;
//
        final Intent intent = new Intent();
        final PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
                intent, 0);
//		notification.setLatestEventInfo(getApplicationContext(), title,
//				contentText, contentIntent);
        //	未升级6.0的api之前使用的方法 end

        //api > 16 兼容至api = 23 20161201 390697
        Notification.Builder notificationBuilder = new Notification.Builder(getApplicationContext());
        Notification notification = notificationBuilder.setContentTitle(title)
                .setContentText(contentText)
                .setSmallIcon(android.R.drawable.stat_sys_download_done)
                .setContentIntent(contentIntent)
                .build();
        notification.flags |= Notification.FLAG_AUTO_CANCEL;
        //api=15 特殊处理

        return notification;
    }

    /**
     * @param title
     * @param what  0:失败,1:成功,2:解析失败
     * @return
     */
    private Notification createDownloadFinishNotification(String title,
                                                          int what, BookEntity bookEntity, final int notificationId) {
        final String tickerText = getTickerText(what);
        final String contentText = getContentText(what);
//		final Notification notification = new Notification(
//				android.R.drawable.stat_sys_download_done, tickerText,
//				System.currentTimeMillis());
//		notification.flags |= Notification.FLAG_AUTO_CANCEL;

		final Intent intent = (what == 1)?getStartEntryCatalogIntent(bookEntity):new Intent();//如果下载成功，点击打开书籍
//        final Intent intent = new Intent();
        final PendingIntent contentIntent = PendingIntent.getActivity(this,
                notificationId, intent, PendingIntent.FLAG_CANCEL_CURRENT);
//		notification.setLatestEventInfo(getApplicationContext(), title,
//				contentText, contentIntent);
        //390697 20161201 兼容6.0
        Notification.Builder notificationBuilder = new Notification.Builder(getApplicationContext());
        Notification notification = notificationBuilder.setContentTitle(title)
                .setContentText(contentText)
                .setSmallIcon(android.R.drawable.stat_sys_download_done)
                .setContentIntent(contentIntent)
                .build();
        notification.flags |= Notification.FLAG_AUTO_CANCEL;
        return notification;
    }

    private Intent getStartEntryCatalogIntent(final BookEntity entity) {
        EntryCatalogUtil catalogUtil = new EntryCatalogUtil();
        Intent intent = catalogUtil.getStartEntryCatalogIntent(
                getApplicationContext(), entity);
        return intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
                | Intent.FLAG_ACTIVITY_NEW_TASK);
    }

    private String getContentText(int what) {
        String contentText = "";
        if (what == 0) {
            contentText = getString(R.string.content_error);
        } else if (what == 1) {
            contentText = getString(R.string.content_success);
        } else if (what == 2) {
            contentText = getString(R.string.book_zip_txt_error_hint);
        }
        return contentText;
    }

    private String getTickerText(int what) {
        String tickerText = "";
        if (what == 0) {
            tickerText = getString(R.string.ticker_error);
        } else if (what == 1) {
            tickerText = getString(R.string.ticker_success);
        } else if (what == 2) {
            tickerText = getString(R.string.book_zip_txt_error_hint);
        }

        return tickerText;
    }

    private Notification createDownloadProgressNotification(String title) {
        final RemoteViews contentView = new RemoteViews(getPackageName(),
                R.layout.download_notification);
        contentView.setTextViewText(R.id.download_notification_title, title);
        contentView.setTextViewText(R.id.download_notification_progress_text,
                "");
        contentView.setProgressBar(R.id.download_notification_progress_bar,
                100, 0, true);

        final PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
                new Intent(), 0);

        final Notification notification = new Notification();
        notification.icon = android.R.drawable.stat_sys_download;
        notification.flags |= Notification.FLAG_ONGOING_EVENT;
        notification.contentView = contentView;
        notification.contentIntent = contentIntent;

        return notification;
    }

    private Notification createAnalisisingNotification(String title) {
        final String contentText = getApplicationContext().getString(
                R.string.analysis_ing_hint);

        final PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
                new Intent(), 0);
//
//		final Notification notification = new Notification();
//		notification.icon = android.R.drawable.stat_sys_download;
//		notification.flags |= Notification.FLAG_ONGOING_EVENT;
//		notification.contentIntent = contentIntent;

//		notification.setLatestEventInfo(getApplicationContext(), title,
//				contentText, contentIntent);

        Notification.Builder notificationBuilder = new Notification.Builder(getApplicationContext());
        Notification notification = notificationBuilder.setContentTitle(title)
                .setContentText(contentText)
                .setSmallIcon(android.R.drawable.stat_sys_download)
                .setContentIntent(contentIntent)
                .build();
        notification.flags |= Notification.FLAG_ONGOING_EVENT;
        return notification;
    }

    /**
     * 更新进度
     */
    private void updateBookProgress(final BookEntity bookEntity,
                                    final int progress) {
        LogUtil.i("startUpdate", "开始更新进度到数据库1");

        HctApplication application = (HctApplication) getApplication();
        DbController dbController = new DbController(application.getDbAdapter());
        bookEntity.progress = progress;
        dbController.updateBookProgress(bookEntity);
    }

    /**
     * 更新进度2
     * 2016 12 16 390778
     * 从list中保存时使用
     */
    private void updateBookProgress(final BookEntity bookEntity) {
        LogUtil.i("startUpdate", "开始更新进度到数据库2");
        HctApplication application = (HctApplication) getApplication();
        DbController dbController = new DbController(application.getDbAdapter());
        dbController.updateBookProgress(bookEntity);
    }

    /**
     * 更新状态
     */
    private void updateBookZipState(final BookEntity bookEntity,
                                    final String state) {
        LogUtil.i("startUpdate", "开始更新状态到数据库1");

        HctApplication application = (HctApplication) getApplication();
        DbController dbController = new DbController(application.getDbAdapter());
        bookEntity.bookZipState = state;
        dbController.updateBookZipState(bookEntity);
    }

    /**
     * 更新状态2
     * 2016 12 16 390778
     * 从list中保存时使用
     */
    private void updateBookZipState(final BookEntity bookEntity) {
        LogUtil.i("startUpdate", "开始更新状态到数据库2");
        HctApplication application = (HctApplication) getApplication();
        DbController dbController = new DbController(application.getDbAdapter());
        dbController.updateBookZipState(bookEntity);
    }

    private void updateBookCannotUpdateState(final BookEntity bookEntity) {

        HctApplication application = (HctApplication) getApplication();
        DbController dbController = new DbController(application.getDbAdapter());

        BookEntity inDbEntity = dbController.getBookEntity(bookEntity.id);
        if (inDbEntity.versionCode.equals(bookEntity.versionCode)) {
            dbController.updateBookBCannotUpdate(bookEntity);
        }

    }

    /**
     * 开始下载资料
     *
     * @param bookEntity
     * @param sslCertificate
     * @param file
     * @param title          390694
     */
    private void startFileDownload(final BookEntity bookEntity,
                                   final String sslCertificate, final File file, final String title) {
        final String urlString = bookEntity.download_url;
        add(urlString);

        final int notificationId = NetworkNotifications.Instance()
                .getBookDownloadingId();
        final Notification progressNotification = createDownloadProgressNotification(title);

        final NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        myOngoingNotifications.add(Integer.valueOf(notificationId));
        notificationManager.notify(notificationId, progressNotification);

        final Handler progressHandler = new Handler() {
            public void handleMessage(Message message) {
                final int progress = message.what;
                if (!downloadingUrlsContains(urlString)) {
                    return;
                }
                /**
                 *2016 12 16 390778
                 * 增加判断
                 * true  进行数据库操作
                 * false  进行保存到list中，等待操作完成后进行插入数据库
                 */
                if (updateDateServicestate) {
                    updateBookProgress(bookEntity, progress);

                    updateBookZipState(
                            bookEntity,
                            HctConstants.ON_ACTIVITY_KEY_BOOK_ZIP_STATE_DOWNLOAD_ING);
                } else {
                    bookEntity.progress = progress;
                    bookEntity.bookZipState = HctConstants.ON_ACTIVITY_KEY_BOOK_ZIP_STATE_DOWNLOAD_ING;
                    bookStateList.add(bookEntity);
                }

                sendDownloadedProgressBroadcast(urlString, false, progress, bookEntity);
                final RemoteViews contentView = (RemoteViews) progressNotification.contentView;

                if (progress < 0) {
                    contentView.setTextViewText(
                            R.id.download_notification_progress_text, "");
                    contentView.setProgressBar(
                            R.id.download_notification_progress_bar, 100, 0,
                            true);
                } else {
                    contentView.setTextViewText(
                            R.id.download_notification_progress_text, ""
                                    + progress + "%");
                    contentView.setProgressBar(
                            R.id.download_notification_progress_bar, 100,
                            progress, false);
                }
                final NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
                notificationManager
                        .notify(notificationId, progressNotification);
            }

        };

        final Handler downloadFinishHandler = new Handler() {
            public void handleMessage(Message message) {
                if (!downloadingUrlsContains(urlString)) {
                    return;
                }
                if (message.what == 1) {
                    /**
                     *2016 12 16 390778
                     * 增加判断
                     * true  进行数据库操作
                     * false  进行保存到list中，等待操作完成后进行插入数据库
                     */
                    if (updateDateServicestate) {
                        updateBookProgress(bookEntity, 100);
                        updateBookZipState(
                                bookEntity,
                                HctConstants.ON_ACTIVITY_KEY_BOOK_ZIP_STATE_ANALISIS_DONE);
                        updateBookCannotUpdateState(bookEntity);
                    } else {
                        bookEntity.bookZipState = HctConstants.ON_ACTIVITY_KEY_BOOK_ZIP_STATE_ANALISIS_DONE;
                        bookEntity.progress = 100;
//						bookStateList.add(bookEntity);
                    }

                    sendDownloadedProgressBroadcast(urlString, true, 100, bookEntity);
                } else if (message.what == 0 || message.what == 2) {

                    /**
                     *2016 12 16 390778
                     * 增加判断
                     * true  进行数据库操作
                     * false  进行保存到list中，等待操作完成后进行插入数据库
                     */
                    if (bookEntity.doWhatClick
                            .equals(HctConstants.ON_ACTIVITY_KEY_DO_UPDATE_CLICK)) {
                        if (updateDateServicestate) {
                            updateBookProgress(bookEntity, 100);
                            updateBookZipState(
                                    bookEntity,
                                    HctConstants.ON_ACTIVITY_KEY_BOOK_ZIP_STATE_ANALISIS_DONE);
                        } else {
                            bookEntity.progress = 100;
                            bookEntity.bookZipState = HctConstants.ON_ACTIVITY_KEY_BOOK_ZIP_STATE_ANALISIS_DONE;
                            bookStateList.add(bookEntity);
                        }

                        sendDownloadedProgressBroadcast(urlString, true, 100, bookEntity);

                    } else {
                        /**
                         *2016 12 16 390778
                         * 增加判断
                         * true  进行数据库操作
                         * false  进行保存到list中，等待操作完成后进行插入数据库
                         */
                        if (updateDateServicestate) {
                            updateBookProgress(bookEntity, 0);
                            updateBookZipState(
                                    bookEntity,
                                    HctConstants.ON_ACTIVITY_KEY_BOOK_ZIP_STATE_DOWNLOAD_FAIL);
                        } else {
                            bookEntity.progress = 0;
                            bookEntity.bookZipState = HctConstants.ON_ACTIVITY_KEY_BOOK_ZIP_STATE_DOWNLOAD_FAIL;
                            bookStateList.add(bookEntity);
                        }
                        sendDownloadedProgressBroadcast(urlString, true, 0, bookEntity);
                    }

                }

                remove(urlString);
                final NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
                notificationManager.cancel(notificationId);
                myOngoingNotifications.remove(Integer.valueOf(notificationId));
                notificationManager.notify(
                        notificationId,
                        createDownloadFinishNotification(title, message.what,
                                bookEntity, notificationId));

                if (!addDownloadFromWaitingUrls()) {
                    doStop();
                }
            }
        };
        final Handler analisisIngHandler = new Handler() {
            public void handleMessage(Message message) {

                if (!downloadingUrlsContains(urlString)) {

                    return;
                }
                if (updateDateServicestate) {
                    /**
                     *2016 12 16 390778
                     * 增加判断
                     * true  进行数据库操作
                     * false  进行保存到list中，等待操作完成后进行插入数据库
                     */
                    updateBookZipState(
                            bookEntity,
                            HctConstants.ON_ACTIVITY_KEY_BOOK_ZIP_STATE_ANALISIS_ING);

                    updateBookProgress(bookEntity, 99);
                } else {
                    bookEntity.progress = 99;
                    bookEntity.bookZipState = HctConstants.ON_ACTIVITY_KEY_BOOK_ZIP_STATE_ANALISIS_ING;
                    bookStateList.add(bookEntity);
                }

                sendDownloadedProgressBroadcast(urlString, true, 99, bookEntity);

                final NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
                notificationManager.cancel(notificationId);
                myOngoingNotifications.remove(Integer.valueOf(notificationId));
                notificationManager.notify(notificationId,
                        createAnalisisingNotification(title));
                doAnalysis(bookEntity, downloadFinishHandler);
            }
        };

        final Handler downloadCancelHandler = new Handler() {
            public void handleMessage(Message message) {

                // if (bookEntity.doWhatClick
                // .equals(HctConstants.ON_ACTIVITY_KEY_DO_UPDATE_CLICK)) {
                // updateBookProgress(bookEntity, 100);
                // updateBookZipState(
                // bookEntity,
                // HctConstants.ON_ACTIVITY_KEY_BOOK_ZIP_STATE_ANALISIS_DONE);
                // sendDownloadedProgressBroadcast(bookEntity.download_url,
                // true, 100);
                // } else {
                // updateBookProgress(bookEntity, 0);
                // updateBookZipState(
                // bookEntity,
                // HctConstants.ON_ACTIVITY_KEY_BOOK_ZIP_STATE_ALREADY_CANCEL);
                // sendDownloadedProgressBroadcast(bookEntity.download_url,
                // true, 0);
                // }
                remove(urlString);
                final NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
                notificationManager.cancel(notificationId);
                myOngoingNotifications.remove(Integer.valueOf(notificationId));
                notificationManager.notify(notificationId,
                        createDownloadCancelNotification(file, title));
                if (!addDownloadFromWaitingUrls()) {
                    doStop();
                }
            }
        };
        final ZLNetworkRequest request = new ZLNetworkRequest(urlString,
                sslCertificate, null) {
            public void handleStream(InputStream inputStream, int length)
                    throws IOException, ZLNetworkException {
                /**
                 * 刷新间隔
                 */
                final int updateIntervalMillis = 2000;

                int downloadedPart = 0;
                long progressTime = System.currentTimeMillis()
                        + updateIntervalMillis;
                if (length <= 0) {
                    progressHandler.sendEmptyMessage(-1);
                }
                OutputStream outStream;
                try {
                    outStream = new FileOutputStream(file);
                } catch (FileNotFoundException ex) {
                    throw new ZLNetworkException(
                            ZLNetworkException.ERROR_CREATE_FILE,
                            file.getPath());
                }
                try {
                    final byte[] buffer = new byte[8192];
                    while (!isCancel(urlString)) {
                        final int size = inputStream.read(buffer);

                        if (size <= 0) {
                            break;
                        }
                        downloadedPart += size;

                        if (length > 0) {
                            final long currentTime = System.currentTimeMillis();
                            if (currentTime > progressTime) {
                                progressTime = currentTime
                                        + updateIntervalMillis;

                                float fPart = Float.valueOf(downloadedPart)
                                        * 100f / Float.valueOf(length);
                                progressHandler.sendEmptyMessage((int) fPart);

                            }
                            /*
                             * if (downloadedPart * 100 / length > 95) { throw
							 * new IOException("debug exception"); }
							 */
                        }
                        outStream.write(buffer, 0, size);
                        /*
                         * try { Thread.currentThread().sleep(200); } catch
						 * (InterruptedException ex) { }
						 */
                    }

                    if (isCancel(urlString)) {
                        downloadCancelHandler.sendEmptyMessage(0);
                    }
                } finally {

                    inputStream.close();
                    outStream.close();
                }
            }
        };

        final Thread downloader = new Thread(new Runnable() {
            public void run() {
                boolean success = false;
                try {
                    ZLNetworkManager.Instance().perform(request, address);
                    success = true;
                } catch (ZLNetworkException e) {
                    e.printStackTrace();
                    file.delete();
                } finally {
                    if (!downloadingUrlsContains(urlString)) {
                        return;
                    }
                    if (success) {
                        analisisIngHandler.sendEmptyMessage(success ? 1 : 0);
                    } else if (!success) {
                        downloadFinishHandler.sendEmptyMessage(0);
                    }

                }
            }
        });
        downloader.setPriority(Thread.MIN_PRIORITY);
        downloader.start();
    }

    /**
     * 发送下载进度的广播
     *
     * @param url
     * @param progress
     * @param bookEntity 2016-12-14 添加书籍实体返回给界面
     */
    private void sendDownloadedProgressBroadcast(String url, boolean isSwitch,
                                                 int progress, BookEntity bookEntity) {

        /**
         * 发送广播
         */
        Intent intent = new Intent();
        intent.setAction(HctConstants.RECEIVER_BOOKSHELF_ACTIVITY_DOWNLOAD_UPDATE);
        intent.putExtra(HctConstants.ON_DOWNLOAD_SERIVE_KEY_DOWNLOAD_URL, url);
        intent.putExtra(
                HctConstants.ON_DOWNLOAD_SERIVE_KEY_SWITCH_DOWNLOAD_STATE,
                isSwitch);
        intent.putExtra(HctConstants.ON_DOWNLOAD_SERIVE_KEY_PROGRESS, progress);
        intent.putExtra(HctConstants.ON_ACTIVITY_KEY_BOOK_ENTITY, bookEntity);
        sendBroadcast(intent);
    }

    private boolean contains(String url) {
        if (downloadingUrlsContains(url) || waitingUrlsContains(url)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * XXX
     */
    private boolean downloadingUrlsContains(String url) {
        for (BookEntity entity : mDownloadingUrls) {
            if (entity.download_url.equals(url)) {
                return true;
            }
        }
        return false;
    }

    private boolean waitingUrlsContains(String url) {
        for (BookEntity entity : mWaitingUrls) {
            if (entity.download_url.equals(url)) {
                return true;
            }
        }
        return false;
    }

    private void add(String url) {
        BookEntity entity = new BookEntity();
        entity.download_url = url;
        mDownloadingUrls.add(entity);
    }

    private void remove(String url) {
        Iterator<BookEntity> keys = mDownloadingUrls.iterator();
        BookEntity key = null;
        while (keys.hasNext()) {
            key = (BookEntity) keys.next();
            if (key.download_url.equals(url)) {
                keys.remove();
            }
        }
    }

    private boolean isCancel(String url) {
        CopyOnWriteArraySet<BookEntity> copySets = new CopyOnWriteArraySet<BookEntity>();
        copySets.addAll(mDownloadingUrls);

        for (BookEntity entity : copySets) {
            if (entity.download_url.equals(url)
                    && entity.bookZipState
                    .equals(HctConstants.ON_ACTIVITY_KEY_BOOK_ZIP_STATE_ALREADY_CANCEL)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 执行解析
     */
    private void doAnalysis(final BookEntity bookEntity,
                            final Handler downloadFinishHandler) {

        String local = BookEntity.makeBookFileName(bookEntity.download_url,
                bookEntity.suffix, getApplicationContext());
        LogUtil.w("localPath", bookEntity.download_url);

        if (local.endsWith(".zip")) {// zip文件 解压
            LogUtil.w("DATA", "下载的文件是压缩文件");
            analysisFile(local, bookEntity, downloadFinishHandler);
        } else {// 普通文件
            LogUtil.w("DATA", "下载的文件是普通文件");
            downloadFinishHandler.sendEmptyMessage(1);
        }

    }

    private void analysisFile(final String filePath,
                              final BookEntity bookEntity, final Handler downloadFinishHandler) {
        final Handler handler = new Handler() {
            public void handleMessage(Message msg) {
                switch (msg.what) {
                    case HctConstants.STATUS_SUCCESS:
                        HctResult hctResult = new HctResult();
                        hctResult = (HctResult) msg.obj;
                        BookZipTxtEntity entity = (BookZipTxtEntity) hctResult.data;

                        downloadFinishHandler.sendEmptyMessage(1);
                        break;
                    case HctConstants.STATUS_FAILD:
                        Toast.makeText(getApplicationContext(),
                                getString(R.string.book_zip_txt_error_hint),
                                Toast.LENGTH_SHORT).show();
                        downloadFinishHandler.sendEmptyMessage(2);
                        break;
                }
            }
        };

        final Thread analysis = new Thread(new Runnable() {
            public void run() {
                Message message = new Message();

                try {
                    HctApplication application = (HctApplication) getApplication();
                    HctController controller = new HctController(application
                            .getDbEntryAdapter());

                    HctResult result = controller.getBookZipTxt(filePath,
                            bookEntity.id);
                    if (result.status == HctConstants.STATUS_SUCCESS) {
                        message.what = result.status;
                        message.obj = result;
                    } else {
                        message.what = HctConstants.STATUS_FAILD;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }

                handler.sendMessage(message);
            }
        });
        analysis.setPriority(Thread.MIN_PRIORITY);
        analysis.start();
    }
}
